--
--
-- Author:      feilong
-- DateTime:    2019-04-27 10:59:15
-- Description: 定时器

local skynet = require "skynet"

local Timer = class("Timer")

function Timer:ctor(interval)

	self.inc = 0 --定时器所走的step
	self.interval = interval or 100
	self.timer_index = 0
	self.callbacks = {} --回调
	self.timer_indexs = {} --定时器句柄
	self.unregister_list = {} --要删除的定时器

	-- skynet.timeout(self.interval, function()
	-- 	self:timeOut()
	-- end)
	local function callback()
		while true do			
			self:timeOut()
			skynet.sleep(self.interval)
		end
	end
	skynet.fork(callback)
end

function Timer:timeOut()
	-- skynet.timeout(self.interval, function()
	-- 	self:timeOut()
	-- end)

	self.inc = self.inc + 1
	local callbacks = self.callbacks[self.inc]
	if not callbacks then
		return
	end

	--把注销的剔除掉
	for i=#self.unregister_list,1,-1 do
		local idx = self.unregister_list[i]
		if callbacks[idx] then
			callbacks[idx] = nil
			self.timer_indexs[idx] = nil
			table.remove(self.unregister_list,i)
		end
	end

	for idx,data in pairs(callbacks) do		

		-- data.func(data.param)
		local ok, res = xpcall(data.func,debug.traceback, data.param)
		if not ok then 
			error_log("________定时器协程挂了一次________", res)
		end
		if data.loop == true and res then --回调返回值为true才可以继续循环
			local index = self.inc + data.sec
			self.timer_indexs[idx] = sec
			if not self.callbacks[index] then
				self.callbacks[index] = {}
			end
			data.start_time = os.time()
			self.callbacks[index][idx] = data
		else
			self.timer_indexs[idx] = nil
		end
	end

	self.callbacks[self.inc] = nil
end

--注册定时器与回调函数
function Timer:register(sec, callback, loop, param)
	if(type(sec)~="number" or sec<=0) then
		print("__Timer:register__参数错误_")
		return
	end
	if(not callback or type(callback)~= "function") then
		print("__Timer:register__参数回调错误_")
		return
	end
	--运行时间
	local index = self.inc + sec

	self.timer_index = self.timer_index + 1
	self.timer_indexs[self.timer_index] = index

	if not self.callbacks[index] then
		self.callbacks[index] = {}
	end

	local callbacks = self.callbacks[index]
	callbacks[self.timer_index] = {
		func = callback,
		param = param,
		sec = sec,
		loop = loop,
		start_time=os.time()
	}
	
	return self.timer_index
end

--删除回调注册
-- idx:定时器句柄
function Timer:unregister(idx)
	if not idx then return end
	local sec = self.timer_indexs[idx]
	if not sec then
		return
	end
	table.insert(self.unregister_list, idx) 
end

--定时器还剩余多少时间
function Timer:leftTime(idx)
	if not idx then
		return 0
	end
	local sec = self.timer_indexs[idx]
	if not sec then
		return 0
	end	
	local start_time = self.callbacks[sec][idx].start_time
	local wait_time = self.callbacks[sec][idx].sec
	local now_time = os.time()	
	return start_time + wait_time - now_time
end



return Timer
